package com.medical.admin.sys.config;

/*
 * @Date : 2024/4/27 下午1:09
 * @Created by Lang
 * @ProjectName : medical-appointment-registration
 */

import com.medical.admin.sys.common.utils.ShiroUtils;
import com.medical.admin.sys.realm.AdminRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
public class ShiroConfig {
    public static final String SHIRO_FILTER_ANON_NAME = "anon";
    public static final String SHIRO_FILTER_AUTH_NAME = "authc";
    public static final String SHIRO_FILTER_ANT_NAME = "/**";

    @Resource
    private ShiroProperties shiroProperties;

    // 将自定义的 realm 类注入到容器中
    @Bean
    public AdminRealm adminRealm(HashedCredentialsMatcher hashedCredentialsMatcher) {
        AdminRealm adminRealm = new AdminRealm();
        adminRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return adminRealm;
    }

    /**
     * 注册 SecurityManager
     * 因为 SecurityManager 是一个接口,DefaultSecurityManager 是它的实现类,
     * 所以只需要将 DefaultSecurityManager 注入容器即可
     *
     * @return
     */
    @Bean
    public DefaultWebSecurityManager defaultSecurityManager(AdminRealm adminRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 配置 realm
        securityManager.setRealm(adminRealm);
        return securityManager;
    }


    /**
     * 配置白名单（哪些访问不需要权限）
     *
     * @return
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition shiroFilter = new DefaultShiroFilterChainDefinition();
        shiroProperties.getList().forEach(path->{
            shiroFilter.addPathDefinition(path,SHIRO_FILTER_ANON_NAME);
        });
        shiroFilter.addPathDefinition(SHIRO_FILTER_ANT_NAME,SHIRO_FILTER_AUTH_NAME);
        return shiroFilter;
    }

    /**
     * 配置加密
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //散列算法
        hashedCredentialsMatcher.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);
        //加密盐
        hashedCredentialsMatcher.setHashIterations(ShiroUtils.HASH_ITERATIONS);
        return hashedCredentialsMatcher;
    }

}

